# app/__init__.py
from flask import Flask
from os.path import *
import sys
from redis.sentinel import Sentinel
from redis import StrictRedis
from rediscluster import StrictRedisCluster

# 将common路径加入模块查询路径
BASE_DIR = dirname(dirname(abspath(__file__)))
sys.path.insert(0, BASE_DIR + '/common')

from app.settings.config import config_dict
from utils.constants import EXTRA_ENV_CONFIG

"""创建flask应用"""


def create_flask_app(type):
    # 创建flask应用
    app = Flask(__name__)
    # 根据类型加载配置子类
    config_class = config_dict[type]
    # 先加载默认配置
    app.config.from_object(config_class)
    # 再加载额外配置
    app.config.from_envvar(EXTRA_ENV_CONFIG, silent=True)
    return app


# redis数据库操作对象
redis_client = None  # type: StrictRedis
# redis主从数据库
redis_master = None  # type: StrictRedis
redis_slave = None  # type: StrictRedis
# 创建集群客户端对象
redis_cluster = None  # type: StrictRedisCluster

"""组件初始化"""


def register_extensions(app):
    from models import db
    db.init_app(app)
    # SQLAlchemy组件初始化
    global redis_client
    redis_client = StrictRedis(host=app.config['REDIS_HOST'], port=app.config['REDIS_PORT'],decode_responses=True)
    # 添加转换器
    from utils.converters import register_converters
    register_converters(app)
    # 添加钩子
    from utils.middlewares import get_userinfo
    app.before_request(get_userinfo)

    # redis集群组件初始化
    global redis_cluster
    redis_cluster = StrictRedisCluster(startup_nodes=app.config['CLUSTER_NODES'], decode_responses=True)
    # 哨兵客户端
    global redis_master, redis_slave
    sentinel = Sentinel(app.config['SENTINEL_LIST'])
    redis_master = sentinel.master_for(app.config['SERVICE_NAME'])
    redis_slave = sentinel.slave_for(app.config['SERVICE_NAME'])

"""注册蓝图"""


def register_bp(app: Flask):
    from app.resources.user import user_bp  # 进行局部导入, 避免组件没有初始化完成
    app.register_blueprint(user_bp)

    from app.resources.article import article_bp
    app.register_blueprint(article_bp)

"""创建应用 和 组件初始化"""


def create_app(type):
    # 创建flask应用
    app = create_flask_app(type)
    # 组件初始化
    register_extensions(app)
    # 注册蓝图
    register_bp(app)

    return app


